/**
 * @file mainwindow.h
 * @brief 主窗口类头文件 - 应用程序的核心控制器
 *
 * MainWindow是整个应用程序的主要容器和控制中心，负责：
 * - 管理所有子窗口和页面切换
 * - 处理用户认证状态
 * - 协调各个服务组件
 * - 管理菜单栏、状态栏、系统托盘
 * - 处理应用程序生命周期事件
 */

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

// Qt核心组件
#include <QMainWindow>          // 主窗口基类
#include <QStackedWidget>       // 堆叠窗口容器，用于页面切换
#include <QMenuBar>             // 菜单栏
#include <QStatusBar>           // 状态栏
#include <QSystemTrayIcon>      // 系统托盘图标
#include <QMenu>                // 菜单组件
#include <QAction>              // 菜单动作
#include <QLabel>               // 标签组件
#include <QTimer>               // 定时器，用于状态更新
#include <QCloseEvent>          // 窗口关闭事件
#include <QResizeEvent>         // 窗口大小改变事件
#include <QSettings>            // 设置存储
#include <QMessageBox>          // 消息框
#include <QDateTime>            // 日期时间

// 项目自定义组件
#include "authservice.h"
#include "../include/gameservice.h"
#include "loginwidget.h"
#include "registerwidget.h"
#include "forgotpasswordwidget.h"
#include "gameserverwidget.h"
#include "settingswidget.h"
#include "sidebarwidget.h"

#include "moderngamecontroller.h"
#include "modernsnakeentrywidget.h"
#include "gameauthprogresswidget.h"
#include "directdatachannel.h"
#include "gamedatapool.h"
#include "networkthread.h"

// 前向声明
struct NetworkWebSocketConfig;
// 删除：未使用的BlankGameWidget
// #include "blankgamewidget.h"

/**
 * @class MainWindow
 * @brief 主窗口类 - 应用程序的主要控制器
 *
 * 继承自QMainWindow，提供完整的窗口管理功能，包括菜单栏、状态栏、
 * 工具栏等标准窗口组件。作为应用程序的核心，负责协调各个子组件
 * 和服务的交互。
 */
class MainWindow : public QMainWindow
{
    Q_OBJECT  // Qt元对象系统宏，启用信号槽机制

public:
    /**
     * @brief 构造函数
     * @param parent 父窗口指针，通常为nullptr表示顶级窗口
     *
     * 初始化主窗口，创建所有子组件，设置布局，建立信号槽连接
     */
    explicit MainWindow(QWidget *parent = nullptr);

    /**
     * @brief 析构函数
     *
     * 清理资源，保存窗口状态和用户设置
     */
    ~MainWindow();

protected:
    /**
     * @brief 窗口关闭事件处理
     * @param event 关闭事件对象
     *
     * 重写QMainWindow的关闭事件，提供用户选择：
     * - 退出程序
     * - 最小化到任务栏
     * - 隐藏到系统托盘
     */
    void closeEvent(QCloseEvent *event) override;

    /**
     * @brief 窗口大小改变事件处理
     * @param event 大小改变事件对象
     *
     * 处理窗口大小变化，可用于响应式布局调整
     */
    void resizeEvent(QResizeEvent *event) override;

    /**
     * @brief 窗口状态改变事件处理
     * @param event 状态改变事件对象
     *
     * 处理窗口状态变化（最小化、最大化等），
     * 用于系统托盘集成和窗口行为控制
     */
    void changeEvent(QEvent *event) override;

private slots:
    // === 认证相关槽函数 ===
    /**
     * @brief 登录成功处理槽
     *
     * 当用户成功登录时调用，执行以下操作：
     * - 更新认证状态
     * - 切换到主页面
     * - 显示侧边栏
     * - 更新用户信息
     * - 调整窗口大小
     */
    void onLoginSucceeded();

    /**
     * @brief 切换到注册页面槽
     *
     * 从登录页面切换到注册页面
     */
    void onSwitchToRegister();

    /**
     * @brief 切换到登录页面槽
     *
     * 从其他页面切换回登录页面
     */
    void onSwitchToLogin();

    /**
     * @brief 切换到忘记密码页面槽
     *
     * 从登录页面切换到密码重置页面
     */
    void onSwitchToForgotPassword();

    /**
     * @brief 需要重新认证槽
     *
     * 当令牌过期或认证失效时调用，强制用户重新登录
     */
    void onAuthenticationRequired();

    // === 菜单动作槽函数 ===
    /**
     * @brief 登出触发槽
     *
     * 处理用户登出操作，清除认证状态，返回登录页面
     */
    void onLogoutTriggered();

    /**
     * @brief 设置触发槽
     *
     * 打开设置页面
     */
    void onSettingsTriggered();

    /**
     * @brief 关于对话框触发槽
     *
     * 显示应用程序信息对话框
     */
    void onAboutTriggered();

    /**
     * @brief 退出应用触发槽
     *
     * 处理应用程序退出，显示确认对话框
     */
    void onExitTriggered();

    // === 系统托盘相关槽函数 ===
    /**
     * @brief 系统托盘图标激活槽
     * @param reason 激活原因（单击、双击等）
     *
     * 处理用户与系统托盘图标的交互
     */
    void onTrayIconActivated(QSystemTrayIcon::ActivationReason reason);

    // === 主题和游戏相关槽函数 ===
    /**
     * @brief 主题改变槽
     * @param theme 新主题名称（"dark" 或 "light"）
     *
     * 应用新主题到整个应用程序
     */
    void onThemeChanged(const QString &theme);

    /**
     * @brief 游戏加入请求槽
     * @param gameType 游戏类型
     *
     * 处理用户请求加入特定类型的游戏
     */
    void onGameJoinRequested(const QString &gameType);

    // === Snake游戏相关槽函数 ===
    /**
     * @brief Snake游戏关闭槽
     *
     * 处理Snake游戏界面关闭，返回主页面
     */


    /**
     * @brief 返回主菜单槽
     *
     * 从Snake游戏返回主菜单
     */


    /**
     * @brief 返回大厅请求槽
     *
     * 处理从游戏界面返回大厅的请求
     */
    void onBackToLobbyRequested();

    /**
     * @brief Snake游戏连接就绪槽
     * @param result 游戏认证结果
     *
     * 当Snake游戏认证成功并准备建立WebSocket连接时调用
     */
    void onSnakeGameConnectionReady(const GameService::GameLoginResult &result);



    // === 游戏认证进度相关槽函数 ===
    /**
     * @brief 认证取消槽
     *
     * 当用户取消游戏认证时调用
     */
    void onAuthenticationCancelled();

    /**
     * @brief 游戏认证成功槽
     * @param result 认证结果
     *
     * 当真实的游戏API认证成功时调用
     */
    void onGameAuthenticationSucceeded(const GameService::GameLoginResult &result);

    /**
     * @brief 创建网络线程
     */
    void createNetworkThread();

    /**
     * @brief 开始WebSocket连接和认证流程（已废弃）
     */
    void startWebSocketConnectionAndAuth();

    /**
     * @brief WebSocket连接成功处理
     */
    void onWebSocketConnected();

    /**
     * @brief WebSocket认证成功处理
     * @param authResult 认证结果
     */
    void onWebSocketAuthenticated(const QJsonObject &authResult);

    /**
     * @brief WebSocket连接错误处理
     * @param error 错误信息
     */
    void onWebSocketConnectionError(const QString &error);

    /**
     * @brief WebSocket认证失败处理
     * @param error 错误信息
     */
    void onWebSocketAuthenticationFailed(const QString &error);

    /**
     * @brief 网络线程游戏消息处理
     * @param message 游戏消息
     */
    void onNetworkGameMessage(const QJsonObject &message);

    /**
     * @brief 游戏认证失败槽
     * @param error 错误信息
     *
     * 当真实的游戏API认证失败时调用
     */
    void onGameAuthenticationFailed(const QString &error);

    /**
     * @brief 游戏模式选择槽
     * @param mode 游戏模式 ("single", "multi", "room")
     *
     * 当用户在游戏入口界面选择游戏模式时调用
     */
    void onGameModeSelected(const QString &mode);

    /**
     * @brief 皮肤设置请求槽
     *
     * 当用户点击皮肤设置按钮时调用
     */
    void onSkinSettingsRequested();

    /**
     * @brief 退出游戏槽函数
     *
     * 当用户在游戏中点击退出游戏按钮时调用，返回游戏服务器选择界面
     */
    void onExitGameClicked();

    /**
     * @brief 启动单人游戏模式（旧版本）
     *
     * 根据Snake Game服务文档实现单人模式
     */
    void startSinglePlayerGame();

    /**
     * @brief 启动现代化单人游戏模式
     *
     * 使用优化后的统一渲染架构和直接数据通道
     */
    void startModernSinglePlayerGame();

    /**
     * @brief 切换到优化的游戏界面
     */
    void switchToOptimizedGameInterface();

    /**
     * @brief 启动优化的游戏
     */
    void startOptimizedGame();

    // 其他游戏模式暂时禁用
    // void startMultiPlayerGame();
    // void startRoomModeGame();

    /**
     * @brief 认证完成槽
     * @param result 认证结果
     *
     * 当游戏认证成功完成时调用
     */
    void onAuthenticationCompleted(const GameService::GameLoginResult &result);

    /**
     * @brief 认证失败槽
     * @param error 错误信息
     *
     * 当游戏认证失败时调用
     */
    void onAuthenticationFailed(const QString &error);

    /**
     * @brief 重试认证槽
     *
     * 当用户请求重试认证时调用
     */
    void onRetryAuthentication();

    /**
     * @brief 空白游戏页面准备就绪槽
     *
     * 当空白游戏页面加载完成并准备启动游戏时调用
     */
    void onBlankGamePageReady();

    /**
     * @brief 更新状态栏槽
     *
     * 定时更新状态栏信息，如连接状态、用户状态等
     */
    void updateStatusBar();

    // === 优化架构信号槽 ===
    /**
     * @brief 游戏状态信息变化槽
     * @param info 游戏状态信息
     */
    void onGameStateInfoChanged(const GameStateInfo &info);

    /**
     * @brief 游戏结束槽
     * @param reason 结束原因
     */
    void onGameEnded(const QString &reason);

    /**
     * @brief 连接错误槽
     * @param error 错误信息
     */
    void onConnectionError(const QString &error);

    /**
     * @brief 游戏错误槽
     * @param error 错误信息
     */
    void onGameError(const QString &error);

    /**
     * @brief 通知网络线程开始发送create_room
     */
    void notifyNetworkThreadToStart();

private:
    // === 游戏会话信息结构 ===
    struct GameSession {
        QString websocketUrl;
        QString gameToken;
        QString playerId;
        QString playerName;
    } m_currentGameSession;
    // === 初始化方法 ===
    /**
     * @brief 设置用户界面
     *
     * 创建和配置所有UI组件：
     * - 中央窗口部件
     * - 侧边栏
     * - 堆叠窗口容器
     * - 各个页面组件
     */
    void setupUI();

    /**
     * @brief 设置菜单栏
     *
     * 创建应用程序菜单：
     * - 游戏菜单（刷新、登出、退出）
     * - 设置菜单（偏好设置）
     * - 帮助菜单（关于、关于Qt）
     */
    void setupMenuBar();

    /**
     * @brief 设置状态栏
     *
     * 创建状态栏组件：
     * - 主状态标签
     * - 连接状态标签
     * - 用户状态标签
     */
    void setupStatusBar();

    /**
     * @brief 设置系统托盘
     *
     * 配置系统托盘功能：
     * - 托盘图标
     * - 托盘菜单
     * - 托盘消息通知
     */
    void setupSystemTray();

    /**
     * @brief 设置信号槽连接
     *
     * 建立所有组件之间的信号槽连接：
     * - 认证服务连接
     * - 游戏服务连接
     * - 侧边栏连接
     * - 菜单动作连接
     */
    void setupConnections();

    // === 主题和样式方法 ===
    /**
     * @brief 应用主题
     * @param theme 主题名称
     *
     * 应用指定主题的样式表到整个应用程序
     */
    void applyTheme(const QString &theme);

    // === 状态管理方法 ===
    /**
     * @brief 保存窗口状态
     *
     * 保存窗口的位置、大小等状态信息到QSettings
     */
    void saveWindowState();

    /**
     * @brief 恢复窗口状态
     *
     * 从QSettings恢复窗口的位置、大小等状态信息
     */
    void restoreWindowState();

    // === 页面切换方法 ===
    /**
     * @brief 显示登录页面
     *
     * 切换到登录页面，隐藏侧边栏和菜单栏
     */
    void showLoginPage();

    /**
     * @brief 显示主页面
     *
     * 切换到主功能页面，显示侧边栏和菜单栏
     */
    void showMainPage();

    /**
     * @brief 显示Snake游戏页面
     *
     * 切换到Snake游戏页面，保持侧边栏可见
     */


    /**
     * @brief 显示Snake游戏入口页面
     *
     * 切换到Snake游戏入口页面，显示游戏模式选择界面
     */
    void showSnakeGameEntryPage();

    /**
     * @brief 显示Snake游戏大厅页面
     * @param websocketUrl WebSocket连接URL
     * @param gameToken 游戏认证令牌
     * @param playerId 玩家ID
     * @param playerName 玩家名称
     *
     * 切换到新的游戏大厅页面，建立WebSocket连接并进行认证
     */
    void showSnakeGameLobby(const QString &websocketUrl, const QString &gameToken,
                           const QString &playerId, const QString &playerName);

    // === 辅助方法 ===
    /**
     * @brief 更新窗口标题
     *
     * 根据当前状态和页面更新窗口标题
     */
    void updateWindowTitle();

    /**
     * @brief 显示通知消息
     * @param title 通知标题
     * @param message 通知内容
     *
     * 通过系统托盘显示通知消息
     */
    void showNotification(const QString &title, const QString &message);

    /**
     * @brief 调整窗口大小模式
     * @param isAuthenticated 是否已认证
     *
     * 根据认证状态调整窗口大小：
     * - 未认证：较小的登录窗口
     * - 已认证：较大的主功能窗口
     */
    void adjustWindowSizeForMode(bool isAuthenticated);

    /**
     * @brief 退出前清理
     *
     * 应用程序退出前的清理工作：
     * - 保存设置
     * - 清理网络连接
     * - 隐藏系统托盘
     */
    void cleanupBeforeExit();

    // === 核心服务组件 ===
    /**
     * @brief 用户认证服务
     *
     * 负责处理所有用户认证相关的业务逻辑：
     * - 用户登录、注册、登出
     * - 令牌管理和验证
     * - 密码重置
     * - 用户信息管理
     */
    AuthService *m_authService;

    /**
     * @brief 游戏服务
     *
     * 负责处理游戏相关的业务逻辑：
     * - 获取游戏服务器列表
     * - 服务器筛选和排序
     * - 加入游戏会话
     * - 游戏状态管理
     */
    GameService *m_gameService;

    // === 主要UI组件 ===
    /**
     * @brief 中央窗口部件
     *
     * QMainWindow的中央部件，包含主要的用户界面布局
     */
    QWidget *m_centralWidget;

    /**
     * @brief 主布局管理器
     *
     * 水平布局，包含侧边栏和主内容区域
     */
    QHBoxLayout *m_mainLayout;

    /**
     * @brief 侧边栏组件
     *
     * 提供导航功能的侧边栏，包含：
     * - 用户信息显示
     * - 主要功能导航
     * - 收缩/展开功能
     */
    SidebarWidget *m_sidebarWidget;

    /**
     * @brief 堆叠窗口容器
     *
     * 管理多个页面的容器，一次只显示一个页面：
     * - 登录页面
     * - 注册页面
     * - 主功能页面等
     */
    QStackedWidget *m_stackedWidget;

    // === 认证相关页面 ===
    /**
     * @brief 登录页面组件
     *
     * 用户登录界面，包含用户名、密码输入和相关操作
     */
    LoginWidget *m_loginWidget;

    /**
     * @brief 注册页面组件
     *
     * 用户注册界面，包含用户信息输入和验证
     */
    RegisterWidget *m_registerWidget;

    /**
     * @brief 忘记密码页面组件
     *
     * 密码重置界面，通过邮箱验证重置密码
     */
    ForgotPasswordWidget *m_forgotPasswordWidget;

    // === 主功能页面 ===
    /**
     * @brief 游戏服务器页面组件
     *
     * 主要功能页面，显示游戏服务器列表和相关操作
     */
    GameServerWidget *m_gameServerWidget;

    /**
     * @brief 设置页面组件
     *
     * 应用程序设置界面，包含各种配置选项
     */
    SettingsWidget *m_settingsWidget;

    /**
     * @brief Snake游戏页面组件
     *
     * Snake游戏主界面，包含游戏大厅、游戏界面、设置等
     */


    /**
     * @brief Snake游戏管理器
     *
     * 用于管理WebSocket连接和游戏状态
     */
    SnakeGameManager *m_snakeGameManager;

    /**
     * @brief 专用网络线程
     *
     * 在独立线程中处理WebSocket连接和消息
     */
    class NetworkThread *m_networkThread;





    /**
     * @brief 现代化Snake游戏组件
     *
     * 现代化的Snake游戏界面，参考市面上优秀贪吃蛇游戏设计
     */
    ModernGameController *m_modernGameController;

    /**
     * @brief 现代化Snake游戏入口组件
     *
     * 现代化的Snake游戏入口界面，替代旧的游戏大厅
     */
    ModernSnakeEntryWidget *m_snakeGameEntryWidget;

    /**
     * @brief 游戏认证进度页面组件
     *
     * 显示游戏认证进度的界面，包含步骤指示器、进度条、动画等
     */
    GameAuthProgressWidget *m_gameAuthProgressWidget;

    // 删除：空白游戏页面组件（未使用）
    // /**
    //  * @brief 空白游戏页面组件
    //  *
    //  * 游戏认证完成后的过渡页面，提供加载动画和欢迎信息
    //  */
    // BlankGameWidget *m_blankGameWidget;

    // === 菜单和工具栏组件 ===
    /**
     * @brief 游戏菜单
     *
     * 主菜单栏中的游戏菜单，包含游戏相关操作
     */
    QMenu *m_gameMenu;

    /**
     * @brief 设置菜单
     *
     * 主菜单栏中的设置菜单，包含配置相关操作
     */
    QMenu *m_settingsMenu;

    /**
     * @brief 帮助菜单
     *
     * 主菜单栏中的帮助菜单，包含帮助和关于信息
     */
    QMenu *m_helpMenu;

    /**
     * @brief 刷新动作
     *
     * 菜单栏中的刷新操作，用于刷新当前页面数据
     */
    QAction *m_refreshAction;

    /**
     * @brief 设置动作
     *
     * 菜单栏中的设置操作，打开设置页面
     */
    QAction *m_settingsAction;

    /**
     * @brief 登出动作
     *
     * 菜单栏中的登出操作，清除认证状态并返回登录页面
     */
    QAction *m_logoutAction;

    /**
     * @brief 退出动作
     *
     * 菜单栏中的退出操作，关闭整个应用程序
     */
    QAction *m_exitAction;

    /**
     * @brief 关于动作
     *
     * 帮助菜单中的关于操作，显示应用程序信息
     */
    QAction *m_aboutAction;

    // === 状态栏组件 ===
    /**
     * @brief 主状态标签
     *
     * 状态栏中显示主要状态信息的标签
     */
    QLabel *m_statusLabel;

    /**
     * @brief 用户状态标签
     *
     * 状态栏中显示当前用户信息的标签
     */
    QLabel *m_userLabel;

    /**
     * @brief 连接状态标签
     *
     * 状态栏中显示网络连接状态的标签
     */
    QLabel *m_connectionLabel;

    // === 系统托盘组件 ===
    /**
     * @brief 系统托盘图标
     *
     * 显示在系统托盘中的应用程序图标，支持：
     * - 右键菜单
     * - 双击激活
     * - 通知消息
     */
    QSystemTrayIcon *m_trayIcon;

    /**
     * @brief 系统托盘菜单
     *
     * 右键点击托盘图标时显示的上下文菜单
     */
    QMenu *m_trayMenu;

    // === 定时器组件 ===
    /**
     * @brief 状态更新定时器
     *
     * 定期更新状态栏信息和其他需要刷新的状态
     */
    QTimer *m_statusTimer;

    // === 配置管理 ===
    /**
     * @brief 应用程序设置
     *
     * 用于持久化存储用户配置和应用程序状态：
     * - 窗口位置和大小
     * - 主题选择
     * - 用户偏好设置
     * - 登录状态
     */
    QSettings *m_settings;

    // === 状态变量 ===
    /**
     * @brief 认证状态标志
     *
     * 标识当前用户是否已通过认证
     * - true: 已认证，显示主功能界面
     * - false: 未认证，显示登录界面
     */
    bool m_isAuthenticated;

    /**
     * @brief 当前主题名称
     *
     * 存储当前应用的主题名称（"dark" 或 "light"）
     */
    QString m_currentTheme;

    /**
     * @brief 当前游戏登录结果
     *
     * 存储最近一次成功的游戏认证结果，用于游戏页面初始化
     */
    GameService::GameLoginResult m_currentGameLoginResult;

    // === 样式配置 ===
    /**
     * @brief 主色调
     *
     * 当前主题的主要颜色，用于按钮、边框等UI元素
     */
    QString m_primaryColor;

    /**
     * @brief 背景颜色
     *
     * 当前主题的背景颜色
     */
    QString m_backgroundColor;

    /**
     * @brief 文字颜色
     *
     * 当前主题的文字颜色
     */
    QString m_textColor;

    // === 优化架构组件 ===
    /**
     * @brief 直接数据通道
     *
     * 优化的数据传递通道，跳过中间层，直接连接WebSocket和渲染器
     */
    DirectDataChannel *m_directDataChannel;

    /**
     * @brief 游戏数据对象池
     *
     * 用于减少内存分配开销的对象池
     */
    GameDataPool *m_gameDataPool;
};

#endif // MAINWINDOW_H
